<template>
  <transition name="msgbox-fade">
    <div class="el-message-box__wrapper"
      tabindex="-1"
      v-show="visible"
      @click.self="handleWrapperClick"
      role="dialog"
      aria-modal="true"
      :aria-label="title || 'dialog'">
      <div
        class="el-message-box"
        :class="[customClass,offsetX, center && 'el-message-box--center',`${$type||'default'}-message-box`]"
        :style="{'width': `${width}px`}"
      >
        <div class="ps-confirm_header">
          <span class="title">
            <!-- <svg-icon :iconClass="appCfg.logo"
              class="svgpc" />
            {{appCfg.name}} -->
            <span class="title-default">{{ title }}</span>
            <div class="svgclose"
              @click="handleAction(distinguishCancelAndClose ? 'close' : 'cancel')"
              v-if="showClose">
              <svg-icon iconClass="close" />
            </div>
          </span>
        </div>
        <div class="el-message-box__content" :class="{'text-message':!showInput}">
          <div class="el-message-box__container">
            <p class="massage_content">
              <svg-icon :iconClass="iconClass"
                v-if="iconClass" />
              <slot>
                <span v-if="!dangerouslyUseHTMLString">{{ message }}</span>
                <p v-else
                  v-html="message"></p>
              </slot>
            </p>
            <p v-if="footerHTMLString" class="footer-message">{{ footerMessage }}</p>
            <p v-if="secondaryText" class="text-danger">{{secondaryText}}</p>
          </div>
          <div class="el-message-box__input"
            v-show="showInput">
            <el-input v-model="inputValue"
              :type="inputType"
              size="small"
              @keydown.enter.native="handleInputEnter"
              @blur="valueTrim"
              :placeholder="inputPlaceholder"
              ref="input"></el-input>
            <div class="el-message-box__errormsg"
              :style="{ visibility: !!editorErrorMessage ? 'visible' : 'hidden' }">{{ editorErrorMessage }}</div>
          </div>
        </div>
        <div class="ps-confirm__btns">
          <el-button :loading="cancelButtonLoading"
            class="message-cancel-btn"
            :class="[ cancelButtonClasses ]"
            v-if="showCancelButton"
            :round="roundButton"
            size="small"
            @click.native="handleAction('cancel')"
            @keydown.enter="handleAction('cancel')">
            {{ cancelButtonText || '取消' }}
          </el-button>
          <el-button :loading="confirmButtonLoading"
            ref="confirm"
            class="message-confirm-btn"
            :class="[ confirmButtonClasses ]"
            v-show="showConfirmButton"
            :round="roundButton"
            size="small"
            @click.native="handleAction('confirm')"
            @keydown.enter="handleAction('confirm')">
            {{ confirmButtonText || '确定' }}
          </el-button>
        </div>
      </div>
    </div>
  </transition>
</template>

<script type="text/babel">
import Popup from 'element-ui/lib/utils/popup'
import Locale from 'element-ui/lib/mixins/locale'
import { addClass, removeClass } from 'element-ui/lib/utils/dom'
import Dialog from 'element-ui/lib/utils/aria-dialog'
// import { menuRouter } from '@/router'

let messageBox
export default {
  mixins: [Popup, Locale],

  props: {
    modal: {
      default: false
    },
    width: {
    // eslint-disable-next-line vue/require-prop-type-constructor
      type: String | Number,
      default: ''
    },
    $type: String,
    lockScroll: {
      default: true
    },
    showClose: {
      type: Boolean,
      default: true
    },
    closeOnClickModal: {
      default: true
    },
    closeOnPressEscape: {
      default: true
    },
    closeOnHashChange: {
      default: true
    },
    center: {
      default: false,
      type: Boolean
    },
    roundButton: {
      default: false,
      type: Boolean
    }
  },

  computed: {
    // ...mapGetters(['appInfo']),
    confirmButtonClasses () {
      return `${this.confirmButtonClass}` || 'el-button--primary'
    },
    cancelButtonClasses () {
      return `${this.cancelButtonClass}`
    }
    // appCfg () {
    //   return this.$myStore.state.system.appCfg
    // }
  },

  methods: {
    getSafeClose () {
      const currentId = this.uid
      return () => {
        this.$nextTick(() => {
          if (currentId === this.uid) this.doClose()
        })
      }
    },
    doClose () {
      if (!this.visible) return
      this.visible = false
      this._closing = true
      this.onClose && this.onClose()
      messageBox.closeDialog() // 解绑
      if (this.lockScroll) {
        setTimeout(this.restoreBodyStyle, 200)
      }
      this.opened = false
      this.doAfterClose()
      setTimeout(() => {
        if (this.action) this.callback(this.action, this)
      })
    },

    handleWrapperClick () {
      if (this.closeOnClickModal) {
        this.handleAction(this.distinguishCancelAndClose ? 'close' : 'cancel')
      }
    },

    handleInputEnter () {
      if (this.inputType !== 'textarea') {
        this.valueTrim()
        return this.handleAction('confirm')
      }
    },
    valueTrim () {
      this.inputValue = this.inputValue.trim()
    },
    handleAction (action) {
      if (this.$type === 'prompt' && action === 'confirm' && !this.validate()) {
        return
      }
      this.action = action
      if (typeof this.beforeClose === 'function') {
        this.close = this.getSafeClose()
        this.beforeClose(action, this, this.close)
      } else {
        this.doClose()
      }
    },

    validate () {
      if (this.$type === 'prompt') {
        const inputPattern = this.inputPattern
        if (inputPattern && !inputPattern.test(this.inputValue || '')) {
          this.editorErrorMessage = this.inputErrorMessage
          addClass(this.getInputElement(), 'invalid')
          return false
        }
        const inputValidator = this.inputValidator
        if (typeof inputValidator === 'function') {
          const validateResult = inputValidator(this.inputValue)
          if (validateResult === false) {
            this.editorErrorMessage = this.inputErrorMessage
            addClass(this.getInputElement(), 'invalid')
            return false
          }
          if (typeof validateResult === 'string') {
            this.editorErrorMessage = validateResult
            addClass(this.getInputElement(), 'invalid')
            return false
          }
        }
      }
      this.editorErrorMessage = ''
      removeClass(this.getInputElement(), 'invalid')
      return true
    },
    getFirstFocus () {
      return this.$el.querySelector('.ps-confirm__btns .el-button')
    },
    getInputElement () {
      const inputRefs = this.$refs.input.$refs
      return inputRefs.input || inputRefs.textarea
    },
    handleClose () {
      this.handleAction('close')
    }
  },

  watch: {
    inputValue: {
      immediate: true,
      handler (val) {
        this.$nextTick(_ => {
          if (this.$type === 'prompt' && val !== null) {
            this.validate()
          }
        })
      }
    },

    visible (val) {
      if (val) {
        this.uid++
        if (this.$type === 'alert' || this.$type === 'confirm') {
          this.$nextTick(() => {
            this.$refs.confirm.$el.focus()
          })
        }
        this.focusAfterClosed = document.activeElement
        messageBox = new Dialog(this.$el, this.focusAfterClosed, this.getFirstFocus())
      }

      // prompt
      if (this.$type !== 'prompt') return
      if (val) {
        setTimeout(() => {
          if (this.$refs.input && this.$refs.input.$el) {
            this.getInputElement().focus()
            this.getInputElement().select()
          }
        }, 500)
      } else {
        this.editorErrorMessage = ''
        removeClass(this.getInputElement(), 'invalid')
      }
    }
  },

  mounted () {
    // const path = location.pathname
    // const offsetPath = menuRouter.map(item => item.path)
    // if (offsetPath.includes(path)) {
    //   this.offsetX = 'message-offset'
    // }
    this.$nextTick(() => {
      if (this.closeOnHashChange) {
        window.addEventListener('hashchange', this.close)
      }
    })
  },

  beforeDestroy () {
    if (this.closeOnHashChange) {
      window.removeEventListener('hashchange', this.close)
    }
    setTimeout(() => {
      messageBox.closeDialog()
    })
  },

  data () {
    return {
      uid: 1,
      title: undefined,
      titleIcon: '',
      message: '',
      secondaryText: '',
      type: '',
      iconClass: '',
      customClass: '',
      offsetX: '',
      showInput: false,
      inputValue: null,
      inputPlaceholder: '',
      inputType: 'text',
      inputPattern: null,
      inputValidator: null,
      inputErrorMessage: '',
      showConfirmButton: true,
      showCancelButton: true,
      action: '',
      confirmButtonText: '',
      cancelButtonText: '',
      confirmButtonLoading: false,
      cancelButtonLoading: false,
      confirmButtonClass: '',
      confirmButtonDisabled: false,
      cancelButtonClass: '',
      editorErrorMessage: null,
      callback: null,
      dangerouslyUseHTMLString: false,
      footerHTMLString: false,
      focusAfterClosed: null,
      isOnComposition: false,
      distinguishCancelAndClose: true
    }
  }
}
</script>
<style lang="scss" scoped>
.el-message-box__wrapper{
  outline: none;
}
.ps-confirm_header {
  display: flex;
  position: relative;
  padding: 20px 20px 4px;
  .title {
    display: flex;
    font-size: 14px;
    text-align: center;
    font-weight: bold;
    // padding: 20px 0 0;
    color: rgba(255, 255, 255, 0.7);
    .title-default {
      color: rgba(255, 255, 255, 0.8);
    }
  }
  .svgpc {
    font-size: 16px;
    margin-right: 5px;
  }
  .svgclose {
    position: absolute;
    right: 20px;
    top: 20px;
    font-size: 16px;
    cursor: pointer;
  }
}
.el-message-box__input {
  padding-top: 10px;
}
.el-message-box {
  width: auto;
  height: auto;
  box-sizing: border-box;
  background: #34353B;
  box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.15);
  border-radius: 10px;
  border: 1px solid rgba(255,255,255,0.2);
  .el-message-box__content {
    padding: 16px 35px 20px;
    // min-height: 106px;
    color: #fff;
    &.text-message{
      display: flex;
      align-items: center;
    }
  }
  &.message-white{
    background-color: #fff;
    border-color: #fff;
    .title,.massage_content{
      color: #333;
    }
    .massage_content .svg-icon {
      font-size: 30px;
      flex: 0 0 30px;
    }
    .el-button.cancel{
      color: #333;
    }
  }
  &.no-modal{
    box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.16);
  }
  .text-danger{
    margin-top: 10px;
    margin-left: 42px;
    font-size: 12px;
    color: #FF6565;
  }
}
.massage_content {
  display: flex;
  align-items: center;
  margin: 0;
  padding: 0;
  .svg-icon {
    font-size: 32px;
    margin-right: 10px;
    flex: 0 0 32px;
  }
  span {
    font-size: 14px;
    text-overflow: -o-ellipsis-lastline;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    word-break: break-word;
    line-height: 22px;
  }
  p {
    line-height: 22px;
  }
}
.ps-confirm__btns {
  padding-bottom: 14px;
  text-align: center;
}
.message-cancel-btn,
.message-confirm-btn {
  padding: 9px 30px;
  background: rgba(255,255,255,0.1);
  border-radius: 5px;
  &.big-btn{
    min-width: 120px;
  }
}
.message-cancel-btn:hover {
  background: rgba(255,255,255,0.2);
}
.message-confirm-btn {
  background: #4E5FFF;
}
.el-button + .el-button {
  margin-left: 16px;
}
.prompt-message-box {
  .el-message-box__content {
    padding-bottom: 5px;
  }
}
// .default-message-box {
//   .el-message-box__content {
//     // padding-top: 30px;
//   }
// }
.el-message-box--center {
  .el-message-box__content {
    display: flex;
    align-items: center;
    justify-content: center;

  }
}
.footer-message{
  margin-top: 20px;
  color:var(--color-primary-1);
  user-select: text;
}
.message-offset{
  margin-left: 160px;
}
</style>
